//=========================================================================
// vsprintf.c (C) Zhao Yanbai
// 	wed, 30 Jul 2008 14:47 +0800
// 	Add %012d %012x %12d %12x Support  Mon, 20 Jul 2009 19:30:34
// ========================================================================
#include"string.h"

char	*itoa(char *s, int n);
char	*itox(char *s, unsigned int n);

int vsprintf(char *buf, const char *fmt, char *args)
{
	char *p = buf;
	unsigned char zeroFlag;
	int nChar;
	char tmp[64];

	while(*fmt)
	{
		if( *fmt != '%' )
		{
			*p++ = *fmt++;
			continue;
		}
		
		fmt++;
		nChar = zeroFlag = 0;
		if(*(fmt) == '0') zeroFlag = 1;
		while(*(fmt) >= '0' && *(fmt) <= '9')
		{
			nChar *= 10;
			nChar = *(fmt) - '0';
			fmt++;
		}

		switch(*fmt)
		{
		case 'c':
			*p++ = *args;
			break;
		case 'd':
			itoa(tmp, *((int*)args));
			nChar -= strlen(tmp);
			if(nChar > 0)
			{
				while(nChar--)
				 *p++ = zeroFlag?'0':' ';
			}
			strcpy(p, tmp);
			p += strlen(tmp);
			break;
		case 's':
			strcpy(p, (const char *)*((unsigned int *) args));
			p += strlen((const char *)*((unsigned int *) args));
			break;
		case 'x':
			itox(tmp, *((unsigned int *) args));
			nChar -= strlen(tmp);
			if(nChar > 0)
			{
				while(nChar--)
				 *p++ = zeroFlag?'0':' ';
			}
			strcpy(p, tmp);
			p += strlen(tmp);
			break;
		default:
			break;
		}
		args += 4;
		fmt++;
	}
	*p = 0;
}

char	*itoa(char *s, int n)
{
	int i;
	char tmp[64];
	if( n & 0x80000000 )
	{
		n	= ~n + 1;
		*s++	= '-';
	}
	i=0;
	do
	{
		tmp[i++]	= (n % 10) + '0';
		n		/= 10;
	}while(n);
	while(i) *s++=tmp[--i];
	*s = 0;
	
}

char	*itox(char *s, unsigned int n)
{
	char *p = s;
	char ch,i,flag = 0;
	
	//*p++	= '0';	*p++	= 'x';

	if(n==0){*p++='0';*p=0;return s;}
	for(i=28; i>=0; i-=4)
	{
		ch	= (n>>i) & 0x0F;
		if(ch >= 0)	ch += '0';
		if(ch > '9')	ch += 7;
		if(ch != '0')	flag = 1;
		if(ch != '0' || flag == 1)
			*p++ = ch;
	}
	*p = 0;
	return s;
}
